﻿using BCCommon;
using BCCommon.FreightEnums;
using BCData.Common.Area;
using BCDto.Common.Area;
using BCDto.Sim.Admin.Admin;
using BCEntity.Common.Area;
using BCEntity.Common.EntityNameConst;
using BCService.Utils;
using System;
using System.Collections.Generic;

namespace BCService.Common.Area
{
    public class CountyService : ICountyService
    {
        private readonly ICountyData countyData;
        private readonly ICityData cityData;
        private readonly IRedisService redisService;
        private readonly string key = string.Format("{0}", EntityNameConst.CountyEntity);

        public CountyService(ICountyData countyData, ICityData cityData,IRedisService redisService)
        {
            this.countyData = countyData;
            this.cityData = cityData;
            this.redisService = redisService;
        }

        public bool Add(CountyRequestDto dto,AdminDto adminDto)
        {
            if (!cityData.CheckExistsByCode(dto.CityCode))
            {
                throw new ArgumentException("城市编码不存在");
            }
            if (countyData.CheckCountyCodeExists(dto.CountyCode, dto.CityCode))
            {
                throw new ArgumentException("区县编码已存在");
            }
            CityEntity cityEntity = this.cityData.GetCity(dto.CityCode);
            CountyEntity entity = dto.As<CountyEntity>();
            entity.ProvinceId = cityEntity.ProvinceId;
            entity.ProvinceCode = cityEntity.ProvinceCode;
            entity.ProvinceName = cityEntity.ProvinceName;
            entity.CityId = cityEntity.CityId;
            entity.CityCode = cityEntity.CityCode;
            entity.CityName = cityEntity.CityName;
            entity.IsEnabled = true;
            entity.Editer = adminDto.FullName;
            return countyData.Add(entity);
        }

        public void Delete(string countyCode)
        {
            if (!countyData.CheckExistsByCode(countyCode))
            {
                throw new ArgumentException("区县编码不存在");
            }
            bool result = countyData.Delete(countyCode);
            if (result)
            {
                string cacheKey = this.redisService.GetKey(key, countyCode);
                redisService.Delete(cacheKey);
            }
        }

        public PageableList<CountyDto> GetCounties(string provinceCode, string cityCode, string countyCode,int index, int size)
        {
            var list = countyData.GetCounties(provinceCode, cityCode, countyCode, index, size, out int dataCount);
            PageableList<CountyDto> pageList = new PageableList<CountyDto>
            {
                Count = dataCount,
                Items = list.As<IEnumerable<CountyDto>>()
            };
            return pageList;
        }
        public CountyDto GetCountyById(long countyId)
        {
            string cacheKey = this.redisService.GetKey(key, countyId);
            var entity = this.redisService.TryGet(cacheKey, () => countyData.GetCounty(countyId));

            return entity.As<CountyDto>();
        }

        public CountyDto GetCountyByCode(string countyCode)
        {
            string cacheKey = this.redisService.GetKey(key, countyCode);
            var entity = this.redisService.TryGet(cacheKey, () => countyData.GetCounty(countyCode));

            return entity.As<CountyDto>();
        }

        public IEnumerable<CountyDto> Query(string provinceCode, string cityCode)
        {
            string cacheKey = this.redisService.GetKey(key, provinceCode, cityCode);
            var entity = this.redisService.TryGet(cacheKey, () => countyData.GetCounties(cityCode));

            return entity.As<IEnumerable<CountyDto>>();
        }

        public IEnumerable<CountyViewDto> Query(long cityId)
        {
            string cacheKey = this.redisService.GetKey(key, cityId);
            var entity = this.redisService.TryGet(cacheKey, () => countyData.GetCounties(cityId));
            return entity.As<IEnumerable<CountyViewDto>>();
        }

        public void Update(CountyPutDto dto,AdminDto adminDto)
        {
            
            if (!countyData.CheckExistsById(dto.CountyId))
            {
                throw new ArgumentException("此区县信息不存在");
            }

            var oldEntity = countyData.GetCounty(dto.CountyId);
            if(oldEntity.CountyCode != dto.CountyCode)
            {
                if (this.countyData.CheckExistsByCode(dto.CountyCode))
                {
                    throw new ArgumentException("此区县编码已存在");
                }
            }
            if (!cityData.CheckExistsByCode(dto.CityCode))
            {
                throw new ArgumentException("城市编码不存在");
            }
            CityEntity cityEntity = this.cityData.GetCity(dto.CityCode);
            var entity = dto.As<CountyEntity>();
            entity.ProvinceId = cityEntity.ProvinceId;
            entity.ProvinceCode = cityEntity.ProvinceCode;
            entity.ProvinceName = cityEntity.ProvinceName;
            entity.CityId = cityEntity.CityId;
            entity.CityCode = cityEntity.CityCode;
            entity.CityName = cityEntity.CityName;
            entity.Editer = adminDto.FullName;
            entity.UpdateTime = DateTime.Now;
            var result = countyData.Update(entity);
            if (result)
            {
                string cacheKey = string.Format("{0}:CountyId={1}", key, dto.CountyId);
                this.redisService.DeleteMultipleKey(cacheKey,false);
            }
        }

        public bool UpdateCountyNegotiatedPrice(string countyCode, bool isNegotiatedPrice)
        {
            return this.countyData.UpdateCountyNegotiatedPrice(countyCode, isNegotiatedPrice);
        }

        public CountyDto UpdateCounty(string editer, string countyCode, string countyName, string provinceCode, string provinceName, string cityCode, string cityName, double longitude, double latitude, string batchNo)
        {
            CountyEntity entity = new CountyEntity()
            {
                CountyCode = countyCode,
                CityCode = cityCode,
                CountyName = countyName,
                CityName = cityName,
                ProvinceCode = provinceCode,
                ProvinceName = provinceName,
                IsDowntown = false,
                CountyHeatLevel = 0,
                ArriveCityDistance = 0,
                CountyEasyBackGoods = EasyBackGoodsType.Normal,
                Editer = editer,
                CountyNegotiatedPrice = false,
                Longitude = longitude,
                Latitude = latitude,
                IsEnabled = true
            };
            int status = 0;
            var countryResult = this.countyData.GetCountyAsync(null, countyName.Substring(0, countyName.Length - 1), countyCode.Substring(4, 2), cityCode).GetAwaiter().GetResult();
            if (countryResult == null)
            {
                while (status == 0)
                {
                    status = countyData.AddCountyAsync(entity, batchNo).GetAwaiter().GetResult();
                }
                //新增零担 整车运费配置
                #region
                //var freightEntity = new FreightConfigurationEntity()
                //{
                //    ProvinceCode = provinceCode,
                //    CityCode = cityCode,
                //    CountyCode = countyCode,
                //    StartPrice = 200M,
                //    StartMileage = 10,
                //    MileagePrice = 3.3M,
                //    Editer = editer
                //};
                //status = 0;
                //while (status == 0)
                //{
                //    status = freightConfigurationData.InsertManyRowAsync(freightEntity).GetAwaiter().GetResult();
                //}
                //var freightExtentionEntity = new FreightConfigurationExtentionEntity()
                //{
                //    ProvinceCode = provinceCode,
                //    CityCode = cityCode,
                //    CountyCode = countyCode,
                //    StartWeight = 0.5M,
                //    EndWeight = 1.4M,
                //    Stere = 2,
                //    StartPrice = 100M,
                //    MileagePrice = 0.6M,
                //    Editer = editer
                //};
                //status = 0;
                //while (status == 0)
                //{
                //    status = freightConfigurationExtentionData.InsertAsync(freightExtentionEntity).GetAwaiter().GetResult();
                //}
                #endregion
            }
            else
            {
                entity.CountyUuid = countryResult.CountyUuid;
                if (countryResult.CountyName == countyName && countryResult.CountyCode == countyCode)
                {
                    while (status == 0)
                    {
                        status = countyData.UpdateCountyAsync(entity, null, null, null).GetAwaiter().GetResult();
                    }
                }
                else
                {
                    while (status == 0)
                    {
                        status = countyData.UpdateCountyAsync(entity, batchNo, countryResult, false).GetAwaiter().GetResult();
                    }
                }
            }
            var result = this.countyData.GetCountyAsync(null, null, countyCode, cityCode).GetAwaiter().GetResult();
            return result.As<CountyDto>();
        }

        public bool UpdateIsEnabled(string batchNo)
        {
            if (!this.countyData.UpdateIsEnabledAsync(batchNo).GetAwaiter().GetResult())
            {
                return false;
            }
            return true;
        }
    }
}
